﻿using System;
using System.Linq;
using System.ComponentModel;
using System.Collections.ObjectModel;
using System.Windows.Input;
using Dropbox.DataHouse.Logic;
using InnovTech.Wpf.Command;
using System.Windows;
using System.Reactive.Linq;
using System.Threading;
using InnovTech.Util.Zip;
using System.IO;
using InnovTech.Data.Dropbox;
using AppLimit.CloudComputing.SharpBox;

namespace Dropbox.DataHouse.View
{
    public class DataHouseViewModel : INotifyPropertyChanged
    {

        public DataHouseViewModel()
        {
            List = new ObservableCollection<FileInformation>();
            Model = new DataHouseModel();
            SyncCmd = new DelegateCommand<DataHouseViewModel>(
                vm =>
                {
                    CurrentActionName = "Syncronization";
                    AnyActionRunning = true;

                    Observable.Start(() =>
                    {
                        ObservableCollection<FileInformation> list = Model.GetFileInfos();
                        vm.List = list;
                        AnyActionRunning = false;
                    });


                });

            AddNewCmd = new DelegateCommand<DataHouseViewModel>(
                vm =>
                {

                    CurrentActionName = "Adding";
                    AnyActionRunning = true;

                    //FileInformation fi = null;
                    Microsoft.Win32.OpenFileDialog dia = new Microsoft.Win32.OpenFileDialog();
                    dia.Multiselect = true;
                    if (dia.ShowDialog().Value)
                    {
                        string[] FileList = dia.FileNames;
                        if (FileList.Length == 0)
                        {
                            
                            return;
                        }
                        SynchronizationContext context = SynchronizationContext.Current;
                        Observable.Start(() =>
                            FileList.Select(file => Model.AddNewFile(file, Progress)).
                            ToObservable()
                            .ObserveOn(context)
                            .Subscribe(file => List.Add(file), () => AnyActionRunning = false)
                        );
                    }
                    else
                        AnyActionRunning = false;
                });

            AddNewByDropCmd = new DelegateCommand<IDataObject>(
                data =>
                {

                    CurrentActionName = "Adding";
                    AnyActionRunning = true;
                    string[] FileList = (string[])data.GetData(DataFormats.FileDrop, false);
                    SynchronizationContext context = SynchronizationContext.Current;
                    Observable.Start(() =>
                        FileList.Select(file =>
                        {
                            bool isZippedDir = false;
                            string filePath = null;
                            if (File.Exists(file))
                                filePath = file;
                            else
                            {
                                VsCodeHandler.DeleteVsUnusfulDirs(file);
                                filePath = SharpZipUtil.CompressFolder(file, Directory.GetCurrentDirectory());
                                isZippedDir = true;
                            }
                            var fileInfo = Model.AddNewFile(filePath, Progress);
                            if(isZippedDir)
                                File.Delete(filePath);
                            return fileInfo;
                        }).
                        ToObservable()
                        .ObserveOn(context)
                        .Subscribe(file => { List.Add(file); }, () => AnyActionRunning = false)
                    );
                });

            DeleteCmd = new DelegateCommand<DataHouseViewModel>(
                vm =>
                {
                    CurrentActionName = "Deleting";
                    AnyActionRunning = true;

                   // Observable.Start<FileInformation>(() => { return Model.DeleteFile(vm.List, vm.SelectedItem); })
                   //.ObserveOn(SynchronizationContext.Current)
                   //     .Subscribe(file => List.Remove(file), () => AnyActionRunning = false);

                    Observable.Start<FileInformation>(() =>
                    {
                        return Model.DeleteFile(vm.List,
                            vm.SelectedItem,
                            () =>
                            {
                                CurrentActionName = "Deleting";
                                AnyActionRunning = true;
                            },
                            () =>
                            {
                                CurrentActionName = string.Empty;
                                CurrentActionState = string.Empty;
                                CurrentActionPercentageProgress = 0;
                                AnyActionRunning = false;
                            },
                            () =>
                            {
                                CurrentActionState = "Delete File " + vm.SelectedItem.Dir + "/" + vm.SelectedItem.Name;
                                CurrentActionPercentageProgress = 100;
                            },
                            () =>
                            {
                                CurrentActionState = "Update file list";
                                CurrentActionPercentageProgress = 0;
                            }, Progress); ;
                    })
                   .ObserveOn(SynchronizationContext.Current)
                        .Subscribe(file => List.Remove(file));
                    
                },
                vm =>
                {
                    return vm.SelectedItem != null;
                });

            DownloadCmd = new DelegateCommand<DataHouseViewModel>(
                vm =>
                {
                    CurrentActionName = "Downloading";
                    AnyActionRunning = true;

                    System.Windows.Forms.FolderBrowserDialog dia = new System.Windows.Forms.FolderBrowserDialog();
                    if (dia.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                    {
                        Observable.Start(() =>
                        {
                            Model.DownloadFile(SelectedItem, dia.SelectedPath, Progress);
                            AnyActionRunning = false;
                        });

                    }
                    else
                    {
                        AnyActionRunning = false;
                    }
                },
                vm =>
                {
                    return vm.SelectedItem != null;
                });

            MinCmd = new DelegateCommand<Application>(
                app =>
                {
                    app.MainWindow.Hide();
                    if (IconWin.DataContext == null)
                    {
                        IconWin.DataContext = new MinIconWindowViewModel();
                    }
                    IconWin.Show();
                });
        }

        private void Progress(object sender, FileDataTransferEventArgs args)
        {
            this.CurrentActionPercentageProgress = args.PercentageProgress;
        }

        MinIconWindow _iconWin;

        MinIconWindow IconWin
        {
            get
            {
                if (_iconWin == null )
                    _iconWin = new MinIconWindow();
                return _iconWin;
            }
        }

        DataHouseModel Model { get; set; }


        ObservableCollection<FileInformation> _list;
        public ObservableCollection<FileInformation> List
        {
            get { return _list; }
            set
            {
                if (_list != value)
                {
                    _list = value;
                    if (PropertyChanged != null)
                    {
                        PropertyChanged(this, new PropertyChangedEventArgs("List"));
                    }
                }
            }
        }

        FileInformation _selectedItem;
        public FileInformation SelectedItem
        {
            get { return _selectedItem; }
            set
            {
                if (_selectedItem != value)
                {
                    _selectedItem = value;
                    if (PropertyChanged != null)
                    {
                        PropertyChanged(this, new PropertyChangedEventArgs("SelectedItem"));
                    }
                }
            }
        }

        String _fileToAdd;

        public string FileToAdd
        {
            get { return _fileToAdd; }
            set
            {
                if (_fileToAdd != value)
                {
                    _fileToAdd = value;
                    if (PropertyChanged != null)
                    {
                        PropertyChanged(this, new PropertyChangedEventArgs("FileToAdd"));
                    }
                }
            }
        }


        bool _anyActionRunning;

        public bool AnyActionRunning
        {
            get { return _anyActionRunning; }
            set
            {
                if (_anyActionRunning != value)
                {
                    _anyActionRunning = value;
                    if (PropertyChanged != null)
                    {
                        PropertyChanged(this, new PropertyChangedEventArgs("AnyActionRunning"));
                    }
                }
            }
        }

        string _currentActionName = "Syncronization dakfjdksf skd ";

        public string CurrentActionName
        {
            get { return _currentActionName; }
            set
            {
                if (_currentActionName != value)
                {
                    _currentActionName = value;
                    if (PropertyChanged != null)
                    {
                        PropertyChanged(this, new PropertyChangedEventArgs("CurrentActionName"));
                    }
                }
            }
        }

        string _currentActionState;

        public string CurrentActionState
        {
            get { return _currentActionState; }
            set
            {
                if (_currentActionState != value)
                {
                    _currentActionState = value;
                    if (PropertyChanged != null)
                    {
                        PropertyChanged(this, new PropertyChangedEventArgs("CurrentActionState"));
                    }
                }
            }
        }

        float _currentActionPercentageProgress;
        public float CurrentActionPercentageProgress
        {
            get { return _currentActionPercentageProgress; }
            set
            {
                if (_currentActionPercentageProgress != value)
                {
                    _currentActionPercentageProgress = value;
                    if (PropertyChanged != null)
                    {
                        PropertyChanged(this, new PropertyChangedEventArgs("CurrentActionPercentageProgress"));
                    }
                }
            }
        }

        public ICommand SyncCmd { get; set; }
        public ICommand DeleteCmd { get; set; }
        public ICommand AddNewCmd { get; set; }
        public ICommand DownloadCmd { get; set; }
        public ICommand AddNewByDropCmd { get; set; }
        public ICommand MinCmd { get; set; }

        public event PropertyChangedEventHandler PropertyChanged;


    }
}
